Documentation Index Fetch the complete documentation index at: https://mintlify.com/jcomte23/Python_vanilla/llms.txt
Use this file to discover all available pages before exploring further.
Overview
This exercise builds a billing system that manages customer registration, product catalogs, invoice creation, and tax calculations. It demonstrates how to build a transaction-based system with running totals and final invoice generation.
Difficulty Level : AdvancedConcepts Covered : Tuples, dictionaries, invoice management, financial calculations, state management, multi-step workflows
What You’ll Learn
Immutable Product Catalog
Use tuples to create read-only product data that cannot be accidentally modified
Customer State Management
Track customer information throughout the session
Invoice Building
Accumulate line items into a complete invoice
Financial Calculations
Calculate line totals, subtotals, IVA (tax), and final totals
Complete Code
Here’s the full billing system implementation:
productos = (
{
"nombre" : "pan" ,
"valor" : 1000
},
{
"nombre" : "galleta" ,
"valor" : 800
},
{
"nombre" : "arina" ,
"valor" : 1500
}
)
documentoCliente = ""
nombreCliente = ""
apellidoCliente = ""
factura = []
while True :
print ()
print ( "########" )
print ( "--MENU--" )
print ( "########" )
menu = """
(1) Registar cliente
(2) Registrar un nuevo producto a la factura
(3) Listar productos actuales de la factura.
(4) Mostrar factura
(5) Apagar el programa
"""
print (menu)
opcionMenu = input ( "INGRESE LA OPCION=>" )
if opcionMenu == "1" :
if (documentoCliente == "" or nombreCliente == "" or apellidoCliente == "" ):
print ( "-------------------" )
print ( "Vamos a registrarte" )
documentoCliente = input ( "ingrese el # documento=>" )
nombreCliente = input ( "ingrese los nombres=>" )
apellidoCliente = input ( "ingrese los apellidos=>" )
print ( "-------------------" )
print ( "Datos registrados" )
print ( "DOC:" , documentoCliente)
print ( "NOMBRES:" , nombreCliente)
print ( "APELLIDOS:" , apellidoCliente)
else :
print ( "-------------------" )
print ( "Ya hay un usuario registrado" )
print ( "DOC:" , documentoCliente)
print ( "NOMBRES:" , nombreCliente)
print ( "APELLIDOS:" , apellidoCliente)
print ( "Estas seguro que quieres actualizarlo?" )
respuesta = input ( "(1) si (2) no =>" )
if respuesta == "1" :
documentoCliente = input ( "ingrese el # documento=>" )
nombreCliente = input ( "ingrese los nombres=>" )
apellidoCliente = input ( "ingrese los apellidos=>" )
print ( "Datos registrados" )
print ( "DOC:" , documentoCliente)
print ( "NOMBRES:" , nombreCliente)
print ( "APELLIDOS:" , apellidoCliente)
print ( "Usuario actualizado" )
elif opcionMenu == "2" :
# aca listamos los productos disponibles
indice = 0
for producto in productos:
print ( f "[ { indice } ] { producto[ "nombre" ] } { producto[ "valor" ] } " )
indice += 1
# en esta parte le pedimos al usuario que nos diga cual producto va agregar a la factura
productoSeleccionado = int ( input ( "ingrese el indice del producto que quieres agregar?=>" ))
cantidad = int ( input ( "cuantas unidades vas a comprar?=>" ))
totalProducto = cantidad * productos[productoSeleccionado][ "valor" ]
# creamos un nuevo diccionario para guardarlo en la factura
nuevoProductoEnFactura = {
"nombre" : productos[productoSeleccionado][ "nombre" ],
"valor" : productos[productoSeleccionado][ "valor" ],
"unidades" : cantidad,
"totalProducto" : totalProducto
}
factura.append(nuevoProductoEnFactura)
print ( "producto agregado a la factura" )
elif opcionMenu == "3" :
valorTotalFactura = 0
for producto in factura:
valorTotalFactura += producto[ "totalProducto" ]
print ( "FACTURA" )
print ( "Datos registrados" )
print ( "DOC:" , documentoCliente)
print ( "NOMBRES:" , nombreCliente)
print ( "APELLIDOS:" , apellidoCliente)
for producto in factura:
print ( f " { producto[ "nombre" ] } { producto[ "valor" ] } " )
print ( "--------------------" )
print (valorTotalFactura)
cantidadProductos = len (factura)
valorNeto = 0
for producto in factura:
valorNeto += producto[ "totalProducto" ]
impuestoIva = valorNeto * 0.19
totalFactura = valorNeto + impuestoIva
print ( "--------------------" )
print ( "productos en factura" )
print ( "--------------------" )
for producto in factura:
print ( f " { producto[ "nombre" ] } { producto[ "valor" ] } * { producto[ "unidades" ] } = { producto[ "totalProducto" ] } " )
print ( "--------------------" )
elif opcionMenu == "4" :
elif opcionMenu == "5" :
print ( "Feliz dia" )
break
else :
print ( "#############################" )
print ( "ingreste una opcion invalida" )
print ( "#############################" )
Code Breakdown
Section 1: Product Catalog Using Tuple
productos = (
{
"nombre" : "pan" ,
"valor" : 1000
},
{
"nombre" : "galleta" ,
"valor" : 800
},
{
"nombre" : "arina" ,
"valor" : 1500
}
)
Why a Tuple? Using a tuple (immutable) instead of a list (mutable) prevents accidental modification of the product catalog. This is a good practice when you want to ensure certain data remains constant throughout the program.
Section 2: State Variables
documentoCliente = ""
nombreCliente = ""
apellidoCliente = ""
factura = []
These variables maintain state throughout the program:
Customer information (document, name, surname) stored as strings
Empty strings indicate no customer is registered
factura list accumulates invoice line items
Section 3: Customer Registration (Option 1)
if opcionMenu == "1" :
if (documentoCliente == "" or nombreCliente == "" or apellidoCliente == "" ):
# First registration
print ( "Vamos a registrarte" )
documentoCliente = input ( "ingrese el # documento=>" )
nombreCliente = input ( "ingrese los nombres=>" )
apellidoCliente = input ( "ingrese los apellidos=>" )
print ( "Datos registrados" )
else :
# Update existing customer
print ( "Ya hay un usuario registrado" )
print ( "Estas seguro que quieres actualizarlo?" )
respuesta = input ( "(1) si (2) no =>" )
if respuesta == "1" :
# Update customer data
Check Existing Customer
Test if any customer field is empty using OR logic
Register or Update
Either collect new data or offer to update existing
Confirm Updates
Ask for confirmation before overwriting customer data
Section 4: Add Product to Invoice (Option 2)
elif opcionMenu == "2" :
# Display available products
indice = 0
for producto in productos:
print ( f "[ { indice } ] { producto[ "nombre" ] } { producto[ "valor" ] } " )
indice += 1
# Get user selection
productoSeleccionado = int ( input ( "ingrese el indice del producto que quieres agregar?=>" ))
cantidad = int ( input ( "cuantas unidades vas a comprar?=>" ))
totalProducto = cantidad * productos[productoSeleccionado][ "valor" ]
# Create invoice line item
nuevoProductoEnFactura = {
"nombre" : productos[productoSeleccionado][ "nombre" ],
"valor" : productos[productoSeleccionado][ "valor" ],
"unidades" : cantidad,
"totalProducto" : totalProducto
}
factura.append(nuevoProductoEnFactura)
Invoice Line Item Structure : Each item in the invoice contains:
nombre: Product name
valor: Unit price
unidades: Quantity purchased
totalProducto: Line total (unit price × quantity)
Section 5: Display Current Invoice (Option 3)
elif opcionMenu == "3" :
valorTotalFactura = 0
for producto in factura:
valorTotalFactura += producto[ "totalProducto" ]
print ( "FACTURA" )
print ( "Datos registrados" )
print ( "DOC:" , documentoCliente)
print ( "NOMBRES:" , nombreCliente)
print ( "APELLIDOS:" , apellidoCliente)
# Calculate totals
valorNeto = 0
for producto in factura:
valorNeto += producto[ "totalProducto" ]
impuestoIva = valorNeto * 0.19
totalFactura = valorNeto + impuestoIva
# Display line items
print ( "productos en factura" )
for producto in factura:
print ( f " { producto[ "nombre" ] } { producto[ "valor" ] } * { producto[ "unidades" ] } = { producto[ "totalProducto" ] } " )
Financial Calculations Breakdown
Subtotal (valorNeto) : Sum of all line item totals
IVA (impuestoIva) : 19% tax on subtotal
Total (totalFactura) : Subtotal + IVA
Formula: Total = Subtotal + (Subtotal × 0.19)
Section 6: Incomplete Feature (Option 4)
elif opcionMenu == "4" :
# Empty - not implemented
Missing Implementation : Option 4 (“Mostrar factura”) is declared in the menu but not implemented. This is likely meant to be the final invoice display, possibly with a different format than option 3.
How to Run
Save the File
Save the code in a file named billing_system.py
Run the Program
Execute from your terminal:
Follow the Workflow
Register a customer (Option 1)
Add products to invoice (Option 2, repeat as needed)
View current invoice (Option 3)
Exit (Option 5)
Example Session
########
--MENU--
########
(1) Registar cliente
(2) Registrar un nuevo producto a la factura
(3) Listar productos actuales de la factura.
(4) Mostrar factura
(5) Apagar el programa
INGRESE LA OPCION=>1
-------------------
Vamos a registrarte
ingrese el # documento=>12345678
ingrese los nombres=>Carlos
ingrese los apellidos=>Rodriguez
-------------------
Datos registrados
DOC: 12345678
NOMBRES: Carlos
APELLIDOS: Rodriguez
INGRESE LA OPCION=>2
[0] pan 1000
[1] galleta 800
[2] arina 1500
ingrese el indice del producto que quieres agregar?=>0
cuantas unidades vas a comprar?=>3
producto agregado a la factura
INGRESE LA OPCION=>2
[0] pan 1000
[1] galleta 800
[2] arina 1500
ingrese el indice del producto que quieres agregar?=>1
cuantas unidades vas a comprar?=>5
producto agregado a la factura
INGRESE LA OPCION=>3
FACTURA
Datos registrados
DOC: 12345678
NOMBRES: Carlos
APELLIDOS: Rodriguez
pan 1000
galleta 800
--------------------
7000
--------------------
productos en factura
--------------------
pan 1000 * 3 = 3000
galleta 800 * 5 = 4000
--------------------
Enhancement Ideas
Ways to Improve This Program
Complete Option 4 : Implement a final formatted invoice display
Payment Methods : Add cash, credit, debit payment options
Change Calculation : Calculate change when customer pays with cash
Invoice Numbering : Add sequential invoice numbers
Date/Time Stamps : Record when each invoice was created
Product Management : Add options to create/update/delete products
Data Persistence : Save invoices and customers to files
Receipt Printing : Generate printable receipt format
Discount System : Apply percentage or fixed discounts
Multiple Tax Rates : Support different tax rates for different products
Update Quantities : Modify quantities after adding to invoice
Remove Items : Delete line items from invoice
Customer History : Track all invoices per customer
Common Issues and Solutions
IndexError when selecting product
Problem : User enters an invalid product index.Solution : Validate index range:productoSeleccionado = int ( input ( "ingrese el indice del producto que quieres agregar?=>" ))
if 0 <= productoSeleccionado < len (productos):
# proceed with adding product
else :
print ( "Indice invalido" )
Problem : Trying to view invoice before adding products.Solution : Check if invoice is empty:if not factura:
print ( "La factura esta vacia. Agrega productos primero." )
else :
# display invoice
Redundant calculations in Option 3
Issue : The code calculates valorTotalFactura and valorNeto separately but they’re the same.Optimization : Remove duplicate calculation:subtotal = sum (producto[ "totalProducto" ] for producto in factura)
iva = subtotal * 0.19
total = subtotal + iva
Real-World Applications
This billing system demonstrates concepts from:
Point of Sale (POS) Systems : Retail checkout systems
Invoice Management : Professional invoicing software
E-commerce Checkout : Online shopping cart completion
Restaurant Billing : Order management and bill generation
Key Concepts Demonstrated
Immutable Data Structures
productos = ( ... ) # Tuple - cannot be modified
Using tuples for the product catalog prevents accidental changes to prices or names.
State Management
documentoCliente = ""
factura = []
Maintaining state across multiple operations is essential for transaction-based systems.
Accumulator Pattern
subtotal = 0
for producto in factura:
subtotal += producto[ "totalProducto" ]
The accumulator pattern is fundamental for calculating running totals.
Confirmation Dialogs
print ( "Estas seguro que quieres actualizarlo?" )
respuesta = input ( "(1) si (2) no =>" )
if respuesta == "1" :
# proceed with update
Asking for confirmation prevents accidental data loss.
Key Takeaways
Tuples provide immutable data structures for constants like product catalogs
Empty strings can indicate “not set” state for customer data
Invoice line items should store all relevant details including calculated totals
Financial calculations must be precise and clearly documented
Multi-step workflows (register → add products → view invoice) are common in business applications
Confirmation dialogs improve user experience and prevent mistakes
Incomplete features (like option 4) should be noted and implemented
State management is crucial for maintaining customer and transaction data across operations